#include "StdAfx.h"
#include "CourbeBezier.h"
#include <vector>
#include <stdlib.h>
using namespace std;
CourbeBezier::CourbeBezier(Tableaux<Points3D> tab):
_pointsDeControle(tab),
_degre(tab.Nb_Effectifs())
{
}
CourbeBezier::CourbeBezier(CourbeBezier &courbre):
_pointsDeControle(courbre._pointsDeControle),
_degre(courbre._degre)
{
}
CourbeBezier::~CourbeBezier(){}

CourbeBezier::CourbeBezier(int taille):_degre(taille),_pointsDeControle(taille)
{
}
void CourbeBezier::setPointControle(Tableaux<Points3D> &tableau)
{
	this->_pointsDeControle = tableau;
	this->_degre = tableau.Nb_Effectifs();
}
void CourbeBezier::ajouterPoint(Points3D point,int pos)
{
	if(pos <0|| pos>_pointsDeControle.Nb_Effectifs())
		pos = _pointsDeControle.Nb_Effectifs();
	_pointsDeControle.Inserer(point,pos);
	_degre = _pointsDeControle.Nb_Effectifs();
}
Points3D CourbeBezier::evaluer(double t)
{
	if(t<0 || t>1)
		throw Exception("t doit etre compris entre 0 et 1");
	double tBarre = 1-t;
	vector<vector<Points3D>> tab(_degre,_degre);
	for(int i =0; i<_degre;i++)
		tab[0][i] = _pointsDeControle[i];

	for(int i=1;i<_degre;i++)
	{
		int limite = _degre - i , j=0;
		for(;j<limite;j++)
			tab[i][j] = tBarre*tab[i-1][j]+t*tab[i-1][j+1];
	}
	return tab[_degre-1][0];
}
Points3D & CourbeBezier::operator [](int i)
{
	if(i<0 || i>= _pointsDeControle.Nb_Effectifs())
		throw out_of_range("Courbe de bezier : Acces en dehors du tableau\n");
	return _pointsDeControle[i];
}
CourbeBezier CourbeBezier::derive()
{
	Tableaux<Points3D> tab;
	for(int i=0;i<_degre-1;i++)
	{
		tab.Inserer(_degre*(_pointsDeControle[i+1]-_pointsDeControle[i]),i);
	}
	return CourbeBezier(tab);
}
const bool CourbeBezier::operator ==(const CourbeBezier &c)
{
	if(_degre != c._degre)
		return false;
	for(int i=0;i<_degre;i++)
		if(!(_pointsDeControle[i] ==c._pointsDeControle[i]))
			return false;
	return true;
}